package com.yss.reportworld.service.impl;

import java.util.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.common.core.exception.BusinessException;
import com.yss.reportworld.domain.Database;
import com.yss.reportworld.enums.ReportWorldDescriptionEnum;
import com.yss.reportworld.enums.ReportWorldEnum;
import com.yss.reportworld.mapper.DatabaseMapper;
import lombok.extern.slf4j.Slf4j;
import com.yss.common.core.utils.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yss.reportworld.service.IDescriptionService;
import com.yss.reportworld.mapper.DescriptionMapper;
import com.yss.reportworld.domain.Description;
import org.springframework.util.CollectionUtils;

/**
 * 报表世界说明信息Service业务层处理
 *
 * @author yss
 * @date 2023-06-05
 */
@Slf4j
@Service
public class DescriptionServiceImpl extends ServiceImpl<DescriptionMapper, Description> implements IDescriptionService {
    @Autowired
    private DatabaseMapper databaseMapper;

    /**
     * 查询报表世界说明信息列表
     *
     * @param description 报表世界说明信息
     * @return 报表世界说明信息
     */
    @Override
    public List<Description> selectDescriptionList(Description description) {
        QueryWrapper<Description> wrapper = new QueryWrapper();
        if (StringUtils.isNull(description)) {
            return this.list(wrapper);
        }
        if (StringUtils.isNotEmpty(description.getName())) {
            wrapper.like("NAME", description.getName());
        }
        if (StringUtils.isNotEmpty(description.getChineseName())) {
            wrapper.like("CHINESE_NAME", description.getChineseName());
        }
        if (StringUtils.isNotEmpty(description.getVersion())) {
            wrapper.eq("VERSION", description.getVersion());
        }
        if (null != description.getStatus()) {
            wrapper.eq("STATUS", description.getStatus());
        }
        // 导出的时候选择了数据，按照选择的数据
        if (StringUtils.isNotEmpty(description.getIds())) {
            List<String> list = JSONArray.parseArray(description.getIds(), String.class);
            if (StringUtils.isNotEmpty(list)) {
                wrapper.in("ID", list);
            }
        }
        return this.list(wrapper);
    }

    /**
     * 校验名称是否唯一
     *
     * @param description
     * @return 结果
     */
    @Override
    public boolean checkDescriptionNameUnique(Description description) {
        String descriptionId = StringUtils.isNull(description.getId()) ? "-1" : description.getId();
        QueryWrapper<Description> wrapper = new QueryWrapper<>();
        wrapper.eq("NAME", description.getName());
        Description info = this.getOne(wrapper);
        if (StringUtils.isNotNull(info) && !info.getId().equals(descriptionId)) {
            return false;
        }
        return true;
    }


    /**
     * 获取策略文件和备份文件 没有配置的基础信息表
     *
     * @return
     */
    public String queryCheckInfo() {
        StringBuffer msgInfo = new StringBuffer();
        try {
            // 获取所有基础数据配置信息，对比是否存在差异
            QueryWrapper<Database> wrapperDatabase = new QueryWrapper<>();
            wrapperDatabase.eq("STATUS", YssStatusEnum.NORMAL.getCode());
            List<Database> list = databaseMapper.selectList(wrapperDatabase);
            if (StringUtils.isEmpty(list)) {
                msgInfo.append("没有获取到基础信息配置！");
                return msgInfo.toString();
            }
            Map<String, String> mapDatabase = new HashMap<>();
            for (Database database : list) {
                if (StringUtils.isNull(database) || StringUtils.isEmpty(database.getCode())) {
                    continue;
                }
                if (StringUtils.oneCase(database.getCode().toUpperCase(), ReportWorldEnum.DATABASE_NOT_CODE.getCode())) {
                    continue;
                }
                mapDatabase.put(database.getCode().toUpperCase().replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), ""), database.getCode());
            }
            this.queryCheckCompareconfig(mapDatabase, msgInfo); //策略文件检查
            this.queryCheckBackupversion(mapDatabase, msgInfo); // 备份文件检查

        } catch (Exception ex) {
            msgInfo.append("对比策略文件和备份文件信息失败：" + ex.getMessage());
        }
        return msgInfo.toString();
    }

    /**
     * 检查策略文件是否配置了完整的基础数据信息
     *
     * @param
     * @throws Exception
     */
    public String queryCheckCompareconfig(Map<String, String> mapDatabase, StringBuffer msgInfo) {
        try {
            // 策略文件
            QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
            descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.COMPARECONFIG.getCode());
            Description description = this.getOne(descriptionQueryWrapper);
            if (null == description || StringUtils.isEmpty(description.getDescription())) {
                msgInfo.append("没有获取到策略文件配置信息！");
                return msgInfo.toString();
            }
            Map<String, String> mapCompare = null;
            List<Object> objectList = JSON.parseArray(description.getDescription());
            if (!CollectionUtils.isEmpty(objectList)) {
                mapCompare = new HashMap<>();
                for (Object object : objectList) {
                    if (StringUtils.isNull(object)) {
                        continue;
                    }
                    Map<String, Object> mapcompare = JSON.parseObject(object.toString(), LinkedHashMap.class);
                    String tableName = (String) mapcompare.get("tableName");
                    if (StringUtils.isEmpty(tableName)) {
                        continue;
                    }
                    mapCompare.put(tableName.toUpperCase(), tableName);
                }
            } else {
                msgInfo.append("没有获取到策略文件的表配置信息！");
            }
            // 检查
            for (Map.Entry<String, String> entry : mapDatabase.entrySet()) {
                // 检查策略文件是不是配置了所有表
                if (!StringUtils.isEmpty(mapCompare) && !mapCompare.containsKey(entry.getKey())) {
                    msgInfo.append("表【" + entry.getKey() + "】在策略文件中未配置，请检查！").append("\r\n");
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
        return msgInfo.toString();
    }

    /**
     * 检查表结构备份是否配置了完整的基础数据信息
     *
     * @param
     * @throws Exception
     */
    public String queryCheckBackupversion(Map<String, String> mapDatabase, StringBuffer msgInfo) {
        try {
            QueryWrapper<Description> descriptionQueryWrapperBack = new QueryWrapper<>();
            descriptionQueryWrapperBack.eq("NAME", ReportWorldDescriptionEnum.BACKUPVERSION.getCode());
            Description descriptionBack = this.getOne(descriptionQueryWrapperBack);
            if (null == descriptionBack || StringUtils.isEmpty(descriptionBack.getDescription())) {
                msgInfo.append("没有获取到备份文件配置信息！");
                return msgInfo.toString();
            }
            Map<String, Object> map = JSON.parseObject(descriptionBack.getDescription(), LinkedHashMap.class);
            Map<String, String> mapTableName = null;
            if (!CollectionUtils.isEmpty(map)) {
                List<String> listTableName = (List<String>) map.get("tableNameList");
                if (CollectionUtils.isEmpty(listTableName)) {
                    return msgInfo.toString();
                }
                mapTableName = new HashMap<>();
                for (String tableName : listTableName) {
                    if (StringUtils.isEmpty(tableName)) {
                        continue;
                    }
                    mapTableName.put(tableName.toUpperCase().replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), ""), tableName.toUpperCase());
                }
            } else {
                msgInfo.append("没有获取到备份表文件的表配置信息！");
            }
            // 检查
            for (Map.Entry<String, String> entry : mapDatabase.entrySet()) {
                // 检查是不是备份文件都配置了所有表
                if (!StringUtils.isEmpty(mapTableName) && !mapTableName.containsKey(entry.getKey())) {
                    msgInfo.append("表【" + entry.getKey() + "】在备份文件中未配置，请检查！").append("\r\n");
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
        return msgInfo.toString();
    }

    /**
     * 获取一个表得策略文件
     *
     * @param tableName
     * @return
     */
    public Object getCompareconfig(String tableName) {
        // 策略文件
        QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
        descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.COMPARECONFIG.getCode());
        Description description = this.getOne(descriptionQueryWrapper);
        if (null == description || StringUtils.isEmpty(description.getDescription())) {
            return null;
        }
        JSONArray objectList = (JSONArray) JSON.parse(description.getDescription(), Feature.OrderedField);
        if (CollectionUtils.isEmpty(objectList)) {
            return null;
        }
        for (Object object : objectList) {
            if (StringUtils.isNull(object)) {
                continue;
            }
            Map<String, Object> mapcompare = JSON.parseObject(object.toString(), LinkedHashMap.class, Feature.OrderedField);
            String tableName2 = (String) mapcompare.get("tableName");
            if (StringUtils.isEmpty(tableName2) || !tableName2.equals(tableName.replace(ReportWorldEnum.RW_DB_SUFFIX.getCode(), ""))) {
                continue;
            }
            return JSON.toJSONString(mapcompare, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                    SerializerFeature.WriteDateUseDateFormat);
        }
        return null;
    }


    /**
     * 修改一个表的策略信息
     *
     * @param updateJson
     * @return
     */
    public void updateCompareconfig(String updateJson) {
        // 策略文件
        QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
        descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.COMPARECONFIG.getCode());
        Description description = this.getOne(descriptionQueryWrapper);
        if (null == description || StringUtils.isEmpty(description.getDescription())) {
            throw new BusinessException("没有获取到策略文件信息");
        }
        JSONArray objectList = (JSONArray) JSON.parse(description.getDescription(), Feature.OrderedField);
        if (CollectionUtils.isEmpty(objectList)) {
            throw new BusinessException("没有获取到策略文件信息");
        }
        List<Object> listCompareNewJson = new ArrayList<>();
        // 修改后的JSON
        Map<String, Object> mapNewJson = JSON.parseObject(updateJson, LinkedHashMap.class, Feature.OrderedField);
        boolean falg = false;
        for (Object object : objectList) {
            if (StringUtils.isNull(object)) {
                continue;
            }
            Map<String, Object> mapcompare = JSON.parseObject(object.toString(), LinkedHashMap.class, Feature.OrderedField);
            String tableName = (String) mapcompare.get("tableName");
            String tableNameNew = (String) mapNewJson.get("tableName");
            if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(tableNameNew)) {
                throw new BusinessException("没有获取到策略文件信息中的表名");
            }
            if (tableName.equals(tableNameNew)) { //存在的就是修改
                listCompareNewJson.add(mapNewJson);
                falg = true;
            } else {
                listCompareNewJson.add(object);
            }
            continue;
        }
        if (!falg) { //没有存在的，就是新增的一个
            listCompareNewJson.add(mapNewJson);
        }
        String newJson = JSON.toJSONString(listCompareNewJson, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        if (StringUtils.isNotEmpty(newJson)) {
            UpdateWrapper<Description> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("NAME", ReportWorldDescriptionEnum.COMPARECONFIG.getCode());
            Description descriptionUpdate = new Description();
            descriptionUpdate.setDescription(newJson);
            this.update(descriptionUpdate, updateWrapper);
        }
    }


    /**
     * 获取备份文件里配置的所有表信息
     *
     * @return
     */
    public List<String> getBackUpTableNames() {
        QueryWrapper<Description> descriptionQueryWrapper = new QueryWrapper<>();
        descriptionQueryWrapper.eq("NAME", ReportWorldDescriptionEnum.BACKUPVERSION.getCode());
        Description description = this.getOne(descriptionQueryWrapper);
        if (null == description || StringUtils.isBlank(description.getDescription())) {
            throw new BusinessException("没有获取到配置的备份表信息，请稍后重试！");
        }
        Map<String, Object> map = JSON.parseObject(description.getDescription(), LinkedHashMap.class);
        if (CollectionUtils.isEmpty(map)) {
            throw new BusinessException("没有获取到配置的备份表信息，请稍后重试！");
        }
        List<String> listTableName = (List<String>) map.get("tableNameList");
        if (CollectionUtils.isEmpty(listTableName)) {
            if (CollectionUtils.isEmpty(map)) {
                throw new BusinessException("没有获取到配置的备份表信息，请稍后重试！");
            }
        }
        return listTableName;
    }
}
